package com.prince.web.service.impl;

import cn.hutool.core.util.StrUtil;
import com.prince.bean.CommonWebResponse;
import com.prince.bean.ResultParams;
import com.prince.bean.WebCode;
import com.prince.constant.Constants;
import com.prince.entity.ProductVo;
import com.prince.entity.RequestOrder;
import com.prince.enums.*;
import com.prince.mapper.*;
import com.prince.mapper.x.InventoryMapperX;
import com.prince.model.*;
import com.prince.page.Page;
import com.prince.util.*;
import com.prince.web.service.UserOrderService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 功能描述: 订单表
 * @Author: 王培喜 58528792@163.com
 * @Date: 2021/4/7 16:03
 */
@Service
public class UserOrderServiceImpl implements UserOrderService {

    @Resource
    private UserOrderMapper userOrderMapper;
    @Resource
    private SalesRecordMapper salesRecordMapper;
    @Resource
    private InventoryMapperX inventoryMapperX;
    @Resource
    private InventoryMapper inventoryMapper;
    @Resource
    private ProductMapper productMapper;
    @Resource
    private CustomerMapper customerMapper;
    @Resource
    private CustomerOrderMapper customerOrderMapper;
    /**
     * 功能描述: 分页查询订单记录
     * @Author: 王培喜 58528792@163.com
     * @Date: 2021/4/6 15:25
     */
    @Override
    public Map<String, Object> findOrderByPage(Map<String, Object> params, Page page) {
        ResultParams response = CommonWebResponse.getSuccessResponseCodeMsgParams();
        UserOrderExample example = new UserOrderExample();
        UserOrderExample.Criteria criteria = example.createCriteria();
        //订单号
        if(MapUtil.isNotEmpty(params,"id")){
            criteria.andIdEqualTo(Integer.valueOf(params.get("id").toString()));
        }
        //支付状态
        if(MapUtil.isNotEmpty(params,"paymentStatus")){
            criteria.andPaymentStatusEqualTo(Integer.valueOf(params.get("paymentStatus").toString()));
        }
        //支付方式
        if(MapUtil.isNotEmpty(params,"paymentType")){
            criteria.andPaymentTypeEqualTo(Integer.valueOf(params.get("paymentType").toString()));
        }
        //客户名称
        if(MapUtil.isNotEmpty(params,"name")){
            criteria.andNameLike("%"+params.get("name")+"%");
            params.put("name","%"+params.get("name")+"%");
        }
        //手机号
        if(MapUtil.isNotEmpty(params,"phone")){
            criteria.andPhoneLike("%"+params.get("phone")+"%");
            params.put("phone","%"+params.get("phone")+"%");
        }
        //地址
        if(MapUtil.isNotEmpty(params,"addr")){
            criteria.andAddrLike("%"+params.get("addr")+"%");
            params.put("addr","%"+params.get("addr")+"%");
        }
        if (MapUtil.isNotEmpty(params, "startTime")) {
            Date startTime = DateUtil.strToDate(params.get("startTime").toString(), "yyyy-MM-dd hh:mm:ss");
            Date endTime = DateUtil.strToDate(params.get("endTime").toString(), "yyyy-MM-dd hh:mm:ss");
            criteria.andCreatedBetween(startTime, endTime);
        }
        int total = userOrderMapper.countByExample(example);
        if(null != page){
            example.setPage(page);
        }
        example.setOrderByClause(" created desc");
        List<UserOrder> list = userOrderMapper.selectByExample(example);
        //订单金额汇总
        response.put("sumMoney",inventoryMapperX.sumOrderMoney(params));
        return response.toHashMapByPage(total,list);
    }
    /**
     * 功能描述: 添加订单
     * @Author: 王培喜 58528792@163.com
     * @Date: 2021/4/6 16:02
     */
    @Override
    @Transactional
    public Map<String, Object> addOrder(RequestOrder order) {
        ResultParams response = CommonWebResponse.getSuccessResponseCodeMsgParams();
        System.err.println("添加订单："+ JsonUtil.toJSONString(order));
        if(null ==order || StrUtil.isEmpty(order.getName()) || ListUtils.isEmpty(order.getProductList()) || StrUtil.isEmpty(order.getProductList().get(0).getName())){
            return CommonWebResponse.getCommonRespCodeMsgParams(WebCode.parameterNull).toHashMap();
        }
        String msg = "";
        try {
            //添加订单
            UserOrder userOrder = new UserOrder();
            userOrder.setCreater(order.getCreater());
            userOrder.setCreated(new Date());
            userOrder.setPaymentStatus(PaymentStatusEnum.PAYED.getCode());
            userOrder.setPaymentType(order.getType());
            userOrder.setName(order.getName());
            userOrder.setPhone(order.getPhone());
            userOrder.setAddr(order.getAddr());
            userOrder.setAmount(new BigDecimal(order.getAmount()));
            userOrder.setMoney(new BigDecimal(order.getTotalPrice()));
            userOrder.setRemark(order.getRemark());
            userOrderMapper.insertSelective(userOrder);
            Integer orderId = userOrder.getId();
            //添加商品
            List<ProductVo> productList = order.getProductList();
            for (ProductVo x : productList) {
                if(StringUtil.isNotEmpty(x.getName()) && x.getNum().doubleValue() > 0 && null != x.getId()) {
                    Inventory inventory = inventoryMapperX.selectByProductId(x.getId());
                    if (null == inventory || inventory.getNumber().doubleValue() < x.getNum().doubleValue()) {
                        msg = x.getName() + "库存不足！";
                        throw new Exception(msg);
                    }
                    x.setRemark(order.getName());
                    addProductAndSubInventory(x, GiftEnum.SHOP, inventory,orderId,order.getCreater());
                }
            }
            //添加赠品
            List<ProductVo> giftList = order.getGiftList();
            for (ProductVo x : giftList) {
                if(StringUtil.isNotEmpty(x.getName()) && x.getNum().doubleValue() > 0 && null != x.getId()) {
                    Inventory inventory = inventoryMapperX.selectByProductId(x.getId());
                    if (null == inventory || inventory.getNumber().doubleValue() < x.getNum().doubleValue()) {
                        msg = x.getName() + "赠品库存不足！";
                        throw new Exception(msg);
                    }
                    x.setRemark(order.getName());
                    addProductAndSubInventory(x, GiftEnum.GIFT, inventory,orderId,order.getCreater());
                }
            }

            //客户id不为空 减钱
            if(null != order.getCustomerId()){
                //通过客户id查询
                Customer customer = customerMapper.selectByPrimaryKey(order.getCustomerId());
                if(null != customer && StringUtil.stringEquals(customer.getName(),order.getName())
                        && StringUtil.stringEquals(customer.getPhone(),order.getPhone())
                        && StringUtil.stringEquals(customer.getAddr(),order.getAddr())
                        && order.getType().equals(PayTypeEnum.AMOUNT.getCode())){
                    msg="客户账户被篡改！";
                    customerAmountChange(customer,orderId,new BigDecimal(order.getAmount()),order.getCreater(),FundDirectionEnum.SUBTRACT);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            //手动回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            //添加失败
            msg = StrUtil.isEmpty(msg) ? WebCode.saveError.msg:msg;
            return CommonWebResponse.getResponseCodeMsgParams("20",msg).toHashMap();
        }
        return response.toHashMap();
    }
    /**
     * 功能描述: 客户金额变动
     * @Author: 王培喜 58528792@163.com
     * @Date: 2021/5/28 16:07
     */
     @Override
     public void customerAmountChange(Customer customer, Integer orderId, BigDecimal amount, String creater, FundDirectionEnum fundDirectionEnum) throws Exception {
         //添加订单
         CustomerOrder co = new CustomerOrder();
         co.setCustomerId(customer.getId());
         co.setAmount(amount);
         co.setPreBalance(customer.getAmount());
         co.setCustomerId(customer.getId());
         co.setUserOrderId(orderId);
         co.setCreater(creater);
         co.setCreated(new Date());
         co.setDescribed(customer.getDescribed());
         //账户变动方向
         co.setDirection(fundDirectionEnum.getCode());
         if(fundDirectionEnum.getCode().equals(FundDirectionEnum.SUBTRACT.getCode())){
             //减少
             co.setPostBalance(customer.getAmount().subtract(co.getAmount()));
             customer.setTotalSpending(customer.getTotalSpending().add(amount));
         }else{
             //增加
             co.setPostBalance(customer.getAmount().add(co.getAmount()));
             customer.setTotalRevenue(customer.getTotalRevenue().add(amount));
         }
         customerOrderMapper.insertSelective(co);
         //变动金额
         customer.setAmount(co.getPostBalance());
         customer.setRemark(customer.getMd5key());
         String key = Constants.USER + customer.getId() + customer.getAmount();
         customer.setMd5key(MD5Util.encrypt(key));
         customer.setDescribed(null);
         int i = customerMapper.updateByKey(customer);
         if(i < 1){
             throw new Exception("客户账户被篡改！");
         }
     }

    /**
     * 功能描述: 订单添加纪录并减少库存
     * @Author: 王培喜 58528792@163.com
     * @Date: 2021/5/7 15:43
     */
    public void addProductAndSubInventory(ProductVo vo, GiftEnum giftEnum,Inventory inventory,Integer orderId,String creater) throws Exception {
        Product product = productMapper.selectByPrimaryKey(vo.getId());
        SalesRecord sr = new SalesRecord();
        sr.setOrderId(orderId);
        sr.setProductId(product.getId());
        sr.setDirection(SaleEnum.ADD.getCode());
        sr.setType(giftEnum.getCode());
        sr.setNumber(vo.getNum());
        sr.setName(product.getName());
        sr.setProductUnit(product.getProductUnit());
        sr.setSpecifications(product.getSpecifications());
        sr.setSupplier(product.getSupplier());
        sr.setPrice(product.getPrice());
        //商品有零售价
        if(giftEnum.getCode().equals(GiftEnum.SHOP.getCode())) {
            sr.setPurchasePrice(new BigDecimal(vo.getPrice()).subtract(vo.getNum()));
        }
        sr.setDel(Constants.YES);
        sr.setCreated(new Date());
        sr.setCreater(creater);
        sr.setRemark(vo.getRemark());
        salesRecordMapper.insertSelective(sr);
        //先更新出库状态
        inventory.setLastLeaveDate(new Date());
        inventoryMapper.updateByPrimaryKeySelective(inventory);

        //减少库存
        BigDecimal source = inventory.getNumber().subtract(vo.getNum());
        String key = Constants.USER + inventory.getProductId() + source;
        key = MD5Util.encrypt(key);
        // 更新库存表 库存减少
        int i=inventoryMapperX.updateInventoryNumber(source, key, inventory.getId(), inventory.getMd5key(),creater);
        if(i< 1){
            //抛异常
            throw new Exception();
        }
    }
    /**
     * 功能描述: 部分退款
     * @Author: 王培喜 58528792@163.com
     * @Date: 2021/4/6 16:02
     */
    @Override
    public Map<String, Object> returnOrder(Integer id, String loginName) {
        ResultParams response = CommonWebResponse.getSuccessResponseCodeMsgParams();
        try{
            SalesRecord salesRecord = salesRecordMapper.selectByPrimaryKey(id);
            if(salesRecord.getDirection().equals(SaleEnum.SUBTRACT.getCode())){
               return CommonWebResponse.getCommonRespCodeMsgParams(WebCode.NOT_REPEAT_RETURN).toHashMap();
            }
            //退款处理
            updateInventory(salesRecord,loginName);
            //更新为部分退款
            UserOrder order = userOrderMapper.selectByPrimaryKey(salesRecord.getOrderId());
            if(null != order){
                //查询是否所有都已退款
                SalesRecordExample example = new SalesRecordExample();
                example.createCriteria().andDelEqualTo(Constants.YES).andOrderIdEqualTo(salesRecord.getOrderId()).andDirectionEqualTo(SaleEnum.ADD.getCode());
                List<SalesRecord> list = salesRecordMapper.selectByExample(example);
                if(ListUtils.isNotEmpty(list)){
                    //不为空代表还未全部退
                    order.setPaymentStatus(PaymentStatusEnum.PART_REFUND.getCode());
                }else{
                    //为空代表全部退完
                    order.setPaymentStatus(PaymentStatusEnum.REFUND.getCode());
                }

                order.setCreater(loginName);
                userOrderMapper.updateByPrimaryKeySelective(order);
            }
        }catch (Exception e){
            //手动回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            //退货失败
            return CommonWebResponse.getCommonRespCodeMsgParams(WebCode.returnError).toHashMap();
        }
        return response.toHashMap();
    }
    /**
     * 功能描述: 退货公共方法
     * @Author: 王培喜 58528792@163.com
     * @Date: 2021/4/16 11:14
     */
    private void updateInventory(SalesRecord x,String name){
        //将销售的商品改为退货并且将商品入库
        x.setUpdater(name);
        x.setDirection(SaleEnum.SUBTRACT.getCode());
        salesRecordMapper.updateByPrimaryKeySelective(x);
        //查询库存
        Inventory inventory = inventoryMapperX.selectByProductId(x.getProductId());
        //更新库存
        inventory.setNumber(inventory.getNumber().add(x.getNumber()));
        String key = Constants.USER + inventory.getProductId()+inventory.getNumber();
        inventoryMapperX.updateInventoryNumber(inventory.getNumber(),key,inventory.getId(),inventory.getMd5key(),name);
    }
    /**
     * 功能描述:  全部退款
     * @Author: 王培喜 58528792@163.com
     * @Date: 2021/4/16 11:00
     */
    @Override
    public Map<String, Object> returnAllOrder(Integer orderId, String loginName) {
        ResultParams response = CommonWebResponse.getSuccessResponseCodeMsgParams();
        try{
            SalesRecordExample example = new SalesRecordExample();
            example.createCriteria().andDelEqualTo(Constants.YES).andOrderIdEqualTo(orderId).andDirectionEqualTo(SaleEnum.ADD.getCode());
            List<SalesRecord> list = salesRecordMapper.selectByExample(example);
            list.forEach(x->{
                //销售状态在做退款处理
                if (x.getDirection().equals(SaleEnum.ADD.getCode())) {
                    //将销售的商品改为退货并且将商品入库
                    updateInventory(x,loginName);
                }
            });
            //更新为全部退款
            UserOrder order = userOrderMapper.selectByPrimaryKey(orderId);
            if(null != order){
                order.setPaymentStatus(PaymentStatusEnum.REFUND.getCode());
                order.setUpdater(loginName);
                userOrderMapper.updateByPrimaryKeySelective(order);
            }

        }catch (Exception e){
            //手动回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            //退货失败
            return CommonWebResponse.getCommonRespCodeMsgParams(WebCode.returnError).toHashMap();
        }
        return response.toHashMap();
    }

}
